package cn.stylefeng.guns.modular.gridsystem.mqtt;

import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.PageUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import cn.stylefeng.guns.core.pojo.page.PageResult;
import cn.stylefeng.guns.core.pojo.response.SuccessResponseData;
import cn.stylefeng.guns.modular.gridsystem.entity.BizExceptionLog;
import cn.stylefeng.guns.modular.gridsystem.mqtt.result.FaultHistory;
import cn.stylefeng.guns.modular.gridsystem.mqtt.result.GatewayChannelStatus;
import cn.stylefeng.guns.modular.gridsystem.service.BizExceptionLogService;
import cn.stylefeng.guns.modular.gridsystem.service.BizExceptionService;
import cn.stylefeng.guns.modular.gridsystem.service.BizGatewayChannelService;
import cn.stylefeng.guns.modular.gridsystem.service.BizGatewayService;
import cn.stylefeng.guns.modular.gridsystem.utils.MyFileUtils;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.extern.slf4j.Slf4j;
import org.eclipse.paho.client.mqttv3.IMqttDeliveryToken;
import org.eclipse.paho.client.mqttv3.MqttCallbackExtended;
import org.eclipse.paho.client.mqttv3.MqttMessage;
import org.springframework.context.ApplicationContext;

import java.io.File;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Arrays;
import java.util.List;

/**
 * @author ssy
 * @date 2023/3/8 11:35
 */
@Slf4j
public class MyMqttClientCallback implements MqttCallbackExtended {

    private BizGatewayService bizGatewayService;
    private BizExceptionLogService bizExceptionLogService;
    private BizExceptionService bizExceptionService;

    private MyMqttClient client;
    private int connectTimes = 0;

    public MyMqttClientCallback(MyMqttClient client) {
        this.client = client;
        ApplicationContext context = SpringUtil.context;  //获取Spring容器
        bizGatewayService = context.getBean(BizGatewayService.class);
        bizExceptionService = context.getBean(BizExceptionService.class);
        bizExceptionLogService = context.getBean(BizExceptionLogService.class);
    }

    @Override
    public void connectComplete(boolean b, String s) {
        log.info("————{} 连接成功!————", client.getClientid());
        //连接成功后，自动订阅主题
        client.subscribe();
        connectTimes = 0;
    }

    @Override
    public void connectionLost(Throwable throwable) {
        log.info("————{} 连接丢失!————{}", client.getClientid(), throwable.getCause());
        //可以在此处做重连处理
        if (connectTimes < client.getMaxConnectTimes()) {
            client.refresh();
            connectTimes++;
        } else {
            client.disconnect();
        }
    }

    @Override
    public void messageArrived(String topic, MqttMessage mqttMessage) throws Exception {
        LocalDateTime dateTime = LocalDateTime.now();
        log.info("[MQTT] {} ----成功接收消息！---- 时间： {}", client.getClientid(), dateTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS")));
        String content = new String(mqttMessage.getPayload());
        log.info("主题 {} 接收到消息 : {}", topic, content);

        try {

            JSONObject jsonObject = JSONUtil.parseObj(content);
            String serialNo = jsonObject.getStr("serialNo");

            if (ObjectUtil.isEmpty(serialNo)) return;

            switch (topic) {
                case MqttTopicConstant.QUERY_GATEWAY_CHANNEL_STATUS:
                    List<GatewayChannelStatus> bizGatewayResults = bizGatewayService.getGatewayChannelStatus();
                    SuccessResponseData successResponseData = new SuccessResponseData(bizGatewayResults);
                    JSONObject jsonObject1 = JSONUtil.parseObj(successResponseData, false);
                    jsonObject1.set("serialNo", serialNo);
                    client.publish(MqttTopicConstant.QUERY_GATEWAY_CHANNEL_STATUS_REPLY, jsonObject1.toString());
                    break;
                case MqttTopicConstant.QUERY_NEW_FAULT_FILE:
                    LambdaQueryWrapper<BizExceptionLog> queryWrapper = new LambdaQueryWrapper<>();
                    queryWrapper.orderByDesc(BizExceptionLog::getCreateTime);
                    queryWrapper.last("limit 1");
                    BizExceptionLog exceptionLog = bizExceptionLogService.getOne(queryWrapper);
                    if (ObjectUtil.isNull(exceptionLog)) {
                        break;
                    }
                    String filePath = MyFileUtils.getUploadPath() + "/" + exceptionLog.getFileName();
                    if (FileUtil.exist(filePath)) {
                        byte[] serialNoBytes = serialNo.getBytes();
                        byte[] bytes = FileUtil.readBytes(filePath);
                        byte[] result = ArrayUtil.addAll(serialNoBytes, bytes);
                        client.publish(MqttTopicConstant.QUERY_NEW_FAULT_FILE_REPLY, result);
                    }
                    break;
                case MqttTopicConstant.QUERY_FAULT_FILE:
                    String voiceUrl = jsonObject.getStr("voiceUrl");
                    if (ObjectUtil.isEmpty(voiceUrl)) break;
                    String path = MyFileUtils.getUploadPath() + "/" + voiceUrl;
                    if (FileUtil.exist(path)) {
                        final byte[] serialNoBytes = serialNo.getBytes();
                        final byte[] bytes = FileUtil.readBytes(path);
                        byte[] result = ArrayUtil.addAll(serialNoBytes, bytes);
                        client.publish(MqttTopicConstant.QUERY_FAULT_FILE_REPLY, result);
                    }
                    break;
                case MqttTopicConstant.QUERY_FAULT_HISTORY:
                    Integer pageNo = jsonObject.getInt("pageNo");
                    Integer pageSize = jsonObject.getInt("pageSize");
                    String startTime = jsonObject.getStr("startTime");
                    String endTime = jsonObject.getStr("endTime");
                    Page page = new Page();
                    page.setCurrent(pageNo);
                    page.setSize(pageSize);
                    PageResult<FaultHistory> pageResult = bizExceptionService.queryFaultHistory(page, startTime, endTime);
                    SuccessResponseData pageResultData = new SuccessResponseData(pageResult);
                    JSONObject parseObj = JSONUtil.parseObj(pageResultData, false);
                    parseObj.set("serialNo", serialNo);
                    client.publish(MqttTopicConstant.QUERY_FAULT_HISTORY_REPLY, parseObj.toString());
                    break;
            }
        } catch (Exception e) {
            log.info(Arrays.toString(mqttMessage.getPayload()));
        }

    }

    @Override
    public void deliveryComplete(IMqttDeliveryToken iMqttDeliveryToken) {
        log.info("[MQTT]{}  ----成功发送消息！---- 时间： {}", client.getClientid(), LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS")));
    }

}



